package com.kjlink.internal.workreport.jira.service;

import cn.xuqiudong.common.base.lookup.Lookup;
import cn.xuqiudong.common.base.model.BaseResponse;
import cn.xuqiudong.common.base.model.PageInfo;
import cn.xuqiudong.common.base.service.BaseService;
import com.kjlink.internal.report4vue.jira.lookup.ProjectJiraLookup;
import com.kjlink.internal.report4vue.jira.request.JiraImportVo;
import com.kjlink.internal.workreport.base.enums.JiraCheckResult;
import com.kjlink.internal.workreport.config.CommonProperties;
import com.kjlink.internal.workreport.config.db.JdbcTemplateConfig;
import com.kjlink.internal.workreport.jira.helper.SqlServerJiraSqlHelper;
import com.kjlink.internal.workreport.jira.mapper.JiraMapper;
import com.kjlink.internal.workreport.jira.model.Jira;
import com.kjlink.internal.workreport.jira.vo.JiraReportDetail;
import com.kjlink.internal.workreport.report.model.WorkReport;
import com.kjlink.internal.workreport.report.service.WorkReportService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Calendar;
import java.util.List;

/**
 * 功能: :jira信息 Service
 *
 * @author Vic.xu
 * @since 2024-04-30 09:37
 */
@Service
public class JiraService extends BaseService<JiraMapper, Jira> {

    /**
     * 工银 jira 数据源
     */
    @Resource(name = JdbcTemplateConfig.JIRA_JDBC_TEMPLATE)
    private JdbcTemplate jiraJdbcTemplate;

    /**
     * 非工银 jira 数据源
     */
    @Resource(name = JdbcTemplateConfig.JIRA2_JDBC_TEMPLATE)
    private JdbcTemplate jira2JdbcTemplate;

    @Resource
    private CommonProperties commonProperties;

    private static final Logger LOGGER = LoggerFactory.getLogger(JiraService.class);

    @Resource
    private WorkReportService workReportService;


    @Override
    protected boolean hasAttachment() {
        return false;
    }


    @Override
    public PageInfo<Jira> page(Lookup lookup) {
        startPage(lookup.getPage(), lookup.getSize());
        List<Jira> dataList = mapper.list(lookup);
        return PageInfo.instance(dataList, lookup);
    }

    /**
     * 查询本地jira
     *
     * @param code jira号
     * @return Jira
     */
    public Jira getJiraByCode(String code) {
        return mapper.getJiraByCode(code);
    }


    /**
     * 从sqlserver获取jira信息
     *
     * @param code jira 号
     * @return Jira
     */
    public Pair<Jira, JiraCheckResult> getJiraFromSqlSerer(String code) {
        try {
            Pair<String, Object[]> pair = SqlServerJiraSqlHelper.buildQueryJiraSqlByCODE(code);
            String sql = pair.getLeft();
            List<Jira> list = fetchJdbcTemplate(code).query(sql, new BeanPropertyRowMapper<>(Jira.class), code);
            if (list.size() > 0) {
                return Pair.of(list.get(0), JiraCheckResult.success);
            }
            return Pair.of(null, JiraCheckResult.notExist);
        } catch (Exception e) {
            LOGGER.error("查询sql server jira失败:{}", e.getMessage(), e);
            return Pair.of(null, JiraCheckResult.fail);
        }
    }


    /**
     * 根据jira号选择数据源
     *
     * @param code jira code
     * @return JdbcTemplate
     */
    private JdbcTemplate fetchJdbcTemplate(String code) {
        if (StringUtils.startsWithIgnoreCase(code, commonProperties.getJiraPrefix())) {
            LOGGER.info("jira号[{}]以工银前缀开头，使用工银jira数据源", code);
            return jiraJdbcTemplate;
        }
        LOGGER.info("jira号[{}]不以工银前缀开头，使用非工银jira数据源", code);
        return jira2JdbcTemplate;
    }

    /**
     * 检测jira号是否存在，先在本系统查询，后去jira系统查询
     *
     * @param code jira号
     * @return whether exist
     */
    public boolean checkJira(String code) {
        Jira jira = getJiraByCode(code);
        if (jira != null) {
            return true;
        }
        String sql = "select count(*) from jiraissue a where a.pkey = ?";
        return fetchJdbcTemplate(code).queryForObject(sql, Integer.class, code) > 0;
    }

    /**
     * 根据code创建jira
     *
     * @param code      jira号
     * @param projectId 项目id
     * @param force     是否强制新增
     * @return BaseResponse with Jira
     */
    public BaseResponse<Jira> createByCode(String code, Integer projectId, boolean force) {
        Jira jira = getJiraByCode(code);
        if (jira != null) {
            return BaseResponse.success(jira);
        }
        Pair<Jira, JiraCheckResult> jiraFromSqlSerer = getJiraFromSqlSerer(code);
        jira = jiraFromSqlSerer.getLeft();

        //如果jira不存在，且不强制新增的时候 则返回错误提示
        if (jira == null && !force) {
            return BaseResponse.error("jira号[" + code + "]不存在于jira系统, 请输入正确的的jira号");
        }

        //能查询出jira的时候 直接入库 且插入父jira
        if (jira != null) {
            jira.setCheckResult(JiraCheckResult.success);
            insertParentJiraFromSqlServer(jira.getPcode(), projectId);
        } else {
            //查询不出来的时候 新增一个最基本的jira
            jira = new Jira();
            jira.setCode(code);
            jira.setCheckResult(jiraFromSqlSerer.getRight());
        }
        jira.setProjectId(projectId);
        jira.setSettleYear(getSettleYear());
        this.save(jira);
        return BaseResponse.success(jira);
    }

    /**
     * 检测jira是否存在， 如果存在于jira系统，则新增到本系统
     */
    public BaseResponse<Boolean> checkAndSaveJira(List<WorkReport> workReports) {
        if (CollectionUtils.isEmpty(workReports)) {
            return BaseResponse.success();
        }
        for (WorkReport workReport : workReports) {
            String code = workReport.getJira();
            if (StringUtils.isNotEmpty(code)) {

                BaseResponse<Jira> createResult = createByCode(code, workReport.getProjectId(), false);
                if (!createResult.isSuccess()) {
                    return BaseResponse.error(createResult.getCode(), createResult.getMsg());
                }
            }
        }
        return BaseResponse.success();
    }

    /**
     * 根据父jira号导入到本地
     */
    public boolean insertParentJiraFromSqlServer(String parentCode, Integer projectId) {
        if (StringUtils.isEmpty(parentCode)) {
            return false;
        }
        Jira jiraByCode = getJiraByCode(parentCode);
        if (jiraByCode != null) {
            if (jiraByCode.getProjectId() == null) {
                Jira user2update = new Jira();
                user2update.setProjectId(projectId);
                user2update.setId(jiraByCode.getId());
                update(user2update);
            }
            LOGGER.info("JIRA号{}已导入本系统,无需重复导入", jiraByCode);
            return false;
        }

        try {
            Pair<Jira, JiraCheckResult> parent = getJiraFromSqlSerer(parentCode);
            Jira jira = parent.getLeft();
            if (jira != null) {
                jira.setCheckResult(JiraCheckResult.success);
                jira.setProjectId(projectId);
                jira.setSettleYear(getSettleYear());
                this.save(jira);
            }
            return true;
        } catch (Exception e) {
            LOGGER.error("插入父jira失败", e);
            return false;
        }
    }


    public int getSettleYear() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }


    /**
     * 统计全部工时，慎用
     */
    public int summaryAll() {
        return summaryUsedTime(null);
    }

    /**
     * 统计工时：
     * 1.1 自身的工时
     * 1.2 子jira的工时
     * 1.3 累计总工时
     * 2.1 父jira自身的工时
     * 2.2 父jira的子jira的工时
     * 2.3 累计父jira总工时
     * @param code jira 号
     */
    public int summaryUsedTime(String code) {
        //统计工时
        int num = mapper.summarySelfUsedTime(code);
        mapper.summarySubUsedTime(code);
        mapper.summaryTotalUsedTime(code);
        //统计其父jira的工时
        if (code != null) {
            String pcode = getPcode(code);
            if (StringUtils.isNotBlank(pcode)) {
                mapper.summarySelfUsedTime(pcode);
                mapper.summarySubUsedTime(pcode);
                mapper.summaryTotalUsedTime(pcode);
            }
        }
        return num;
    }

    /**
     * 获取父jira 号
     */
    public String getPcode(String code) {
        if (code == null) {
            return null;
        }
        return mapper.getPcode(code);
    }



    public JiraReportDetail summaryAndGetReportDetail(String code) {
        if (code == null) {
            return null;
        }
        summaryUsedTime(code);
        return getJiraReportDetail(code);
    }

    /**
     * 一个jira的工时详情，包括子jira的工时
     *
     * @param code jira code
     * @return JiraReportDetail
     */
    public JiraReportDetail getJiraReportDetail(String code) {
        Jira entity = getJiraByCode(code);
        if (entity == null) {
            return null;
        }
        JiraReportDetail detail = new JiraReportDetail();
        detail.setJira(entity);
        List<WorkReport> workReports = workReportService.findWorkReportByJira(entity.getCode());
        detail.setWorkReports(workReports);
        List<WorkReport> subWorkReports = workReportService.findWorkReportByParentJira(entity.getCode());
        detail.setSubWorkReports(subWorkReports);
        return detail;
    }

    public List<Jira> getJiraList(ProjectJiraLookup lookup) {
        return mapper.getJiraList(lookup);
    }

    /**
     * 批量更新项目id
     */
    public int batchUpdateProjectId(JiraImportVo vo) {
        if (vo == null || CollectionUtils.isEmpty(vo.getCodes()) || vo.getProjectId() == null) {
            return 0;
        }
        return mapper.batchUpdateProjectId(vo);
    }

    /**
     * 获取未关闭的jira 列表
     */
    public List<Jira> getNotClosedJira(int size) {
        return mapper.getNotClosedJira(size);
    }

    /**
     * 清空计划时间
     * @param id
     */
    public int clearPlanDate(Integer id) {
        return mapper.clearPlanDate(id);
    }
}
